<template>
  <div class="layout-affix-tag">
    <a-tabs
      v-model="tabActive"
      hide-add
      type="editable-card"
      @tabClick="handleTabClick"
      @edit="handleTabRemove"
    >
      <template #tabBarExtraContent>
        <a-dropdown placement="bottomRight">
          <div class="layout-affix-drop">
            <a-icon
              type="down"
              style="fontsize: 14px"
            />
          </div>
          <a-menu
            slot="overlay"
            @click="handleCommand"
          >
            <a-menu-item key="refreshRoute">
              <a-icon type="redo" />
              <span>刷新页面</span>
            </a-menu-item>
            <a-menu-item key="closeOtherstabs">
              <a-icon type="close" />
              <span>关闭其他</span>
            </a-menu-item>
            <a-menu-item key="closeLefttabs">
              <a-icon type="vertical-right" />
              <span>关闭左侧</span>
            </a-menu-item>
            <a-menu-item key="closeRighttabs">
              <a-icon type="vertical-left" />
              <span>关闭右侧</span>
            </a-menu-item>
            <a-menu-item key="closeAlltabs">
              <a-icon
                type="close-circle"
                theme="filled"
              />
              <span>全部关闭</span>
            </a-menu-item>
          </a-menu>
        </a-dropdown>
      </template>
      <template v-for="route in visitedRoutes">
        <a-tab-pane
          v-if="route.path"
          :key="route.path"
          :tab="route.title || (route.meta && route.meta.title)"
          :closable="!isAffix(route)"
        />
      </template>
    </a-tabs>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'

export default {
  props: {
    menus: {
      type: Array,
      default: () => {
        return []
      }
    }
  },
  data() {
    return {
      tabActive: '',
      affixtabs: []
    }
  },
  computed: {
    ...mapGetters({
      visitedRoutes: 'tabview/visitedRoutes'
    })
  },
  watch: {
    $route: {
      handler() {
        let tabActive = ''
        this.initTabs()
        this.addTabs()
        this.visitedRoutes.forEach((item) => {
          if (item.path === this.$route.path) {
            tabActive = item.path
          }
        })
        this.tabActive = tabActive
      },
      immediate: true
    }
  },
  methods: {
    /**
     * 点击tab，切换页面
     */
    handleTabClick(tab) {
      const route = this.visitedRoutes.filter((item) => {
        if (tab === item.path) return item
      })[0]

      if (this.$route.path !== route.path) {
        this.$router.push({
          path: route.path,
          query: route.query,
          fullPath: route.fullPath
        })
      } else {
        return false
      }
    },

    /**
     * 关闭tab
     */
    async handleTabRemove(tabActive) {
      let view
      this.visitedRoutes.forEach((item) => {
        if (tabActive === item.path) {
          view = item
        }
      })
      const { visitedRoutes } = await this.$store.dispatch('tabview/delRoute', view)
      if (this.isActive(view)) {
        this.toLastTag(visitedRoutes)
      }
    },

    /**
     * tabview菜单
     */
    handleCommand({ key }) {
      switch (key) {
        case 'refreshRoute':
          this.refreshRoute()
          break
        case 'closeOtherstabs':
          this.closeOtherstabs()
          break
        case 'closeLefttabs':
          this.closeLefttabs()
          break
        case 'closeRighttabs':
          this.closeRighttabs()
          break
        case 'closeAlltabs':
          this.closeAlltabs()
          break
      }
    },

    /**
     * 刷新当前页面
     */
    refreshRoute() {
      this.$baseEventBus.$emit('reload-router-view')
    },

    /**
     * 刷新其他页面
     */
    async closeOtherstabs() {
      const view = await this.toThisTag()
      await this.$store.dispatch('tabview/delOthersRoutes', view)
    },

    /**
     * 刷新左侧页面
     */
    async closeLefttabs() {
      const view = await this.toThisTag()
      await this.$store.dispatch('tabview/delLeftRoutes', view)
    },

    /**
     * 刷新右侧页面
     */
    async closeRighttabs() {
      const view = await this.toThisTag()
      await this.$store.dispatch('tabview/delRightRoutes', view)
    },

    /**
     * 关闭全部页面
     */
    async closeAlltabs() {
      const view = await this.toThisTag()
      const { visitedRoutes } = await this.$store.dispatch('tabview/delAllRoutes')
      if (this.affixtabs.some((tag) => tag.path === view.path)) {
        return
      }
      this.toLastTag(visitedRoutes)
    },

    /**
     * 一直存在的路由，如“首页”这类
     */
    isAffix(tag) {
      return tag.meta && tag.meta.affix
    },
    isActive(route) {
      return route.path === this.$route.path
    },
    filterAffixtabs(routes) {
      let tabs = []

      routes.forEach((route) => {
        if (route.meta && route.meta.affix) {
          tabs.push({
            fullPath: route.path,
            path: route.path,
            title: route.title,
            meta: { ...route.meta }
          })
        }
        if (route.children) {
          const temptabs = this.filterAffixtabs(route.children)
          if (temptabs.length >= 1) {
            tabs = [...tabs, ...temptabs]
          }
        }
      })
      return tabs
    },

    /**
     * 下一级tab页面
     */
    toLastTag(visitedRoutes) {
      const latestView = visitedRoutes.slice(-1)[0]
      if (latestView) {
        this.$router.push({
          path: latestView.path,
          query: latestView.query
        })
      } else {
        this.$router.push('/')
      }
    },
    async toThisTag() {
      const view = this.visitedRoutes.filter((item) => {
        if (item.path === this.$route.fullPath) {
          return item
        }
      })[0]
      if (this.$route.path !== view.path) {
        this.$router.push(view)
      }
      return view
    },

    /**
     * 初始化tabs
     */
    initTabs() {
      const affixtabs = (this.affixtabs = this.filterAffixtabs(this.menus))

      for (const tag of affixtabs) {
        this.$store.dispatch('tabview/addVisitedRoute', tag)
      }
    },

    /**
     * 添加tab
     */
    addTabs() {
      const { name } = this.$route
      if (name) {
        this.$store.dispatch('tabview/addVisitedRoute', this.$route)
      }
      return false
    }
  },
  mounted() {}
}
</script>

<style lang="less">
@layoutTabH: 32px;

.layout-affix-tag {
  background-color: @colorBg;
  height: 52px;
  padding: 10px 20px;

  .ant-tabs.ant-tabs-card {
    .ant-tabs-bar {
      margin: auto;
      border: none;

      .ant-tabs-extra-content {
        line-height: @layoutTabH;
      }

      .ant-tabs-nav-container {
        height: auto;

        .ant-tabs-tab-arrow-show {
          .anticon {
            font-size: 16px;
            font-weight: bold;
          }
        }

        .ant-tabs-tab {
          height: @layoutTabH;
          line-height: @layoutTabH;
          margin-right: 6px;
          border-radius: 3px;
          background-color: #fff;
          border: none;
          color: #808695;
          opacity: 0.7;

          &:hover {
            opacity: 1;
          }

          &-active {
            color: @primary;
            opacity: 1;
          }

          .ant-tabs-close-x {
            font-size: 10px;
            line-height: 14px;
            width: 18px;
            margin-left: 6px;
            opacity: 0.6;
            text-align: center;
          }
        }
      }
    }
  }
}

.layout-affix-drop {
  cursor: pointer;
  background: #fff;
  border-radius: 3px;
  width: 32px;
  text-align: center;
}
</style>
